package marchsoft.modules.tiku.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import marchsoft.base.PageVO;
import marchsoft.enums.ResultEnum;
import marchsoft.exception.BadRequestException;
import marchsoft.modules.tiku.entity.EStudyData;
import marchsoft.modules.tiku.entity.dto.EStudyDataDto;
import marchsoft.modules.tiku.entity.dto.StudyDataQueryCriteria;
import marchsoft.modules.tiku.mapper.EStudyDataMapper;
import marchsoft.modules.tiku.service.IEStudyDataService;
import marchsoft.base.BasicServiceImpl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import marchsoft.utils.FileUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
* <p>
* 学习资料表 服务实现类
* </p>
*
* @author zsy
* @since 2022-03-29
*/
@Service
@RequiredArgsConstructor
public class EStudyDataServiceImpl extends BasicServiceImpl<EStudyDataMapper, EStudyData> implements IEStudyDataService {

    private final EStudyDataMapper eStudyDataMapper;
    private final RestHighLevelClient restHighLevelClient;

    @Override
    public void updateIntro(EStudyData eStudyData) {
        eStudyDataMapper.updateIntro(eStudyData);
    }

    @Override
    public IPage<EStudyDataDto> getAll(EStudyDataDto eStudyDataDto, PageVO pageVO) {
        QueryWrapper<Object> query = new QueryWrapper<>();

        if(ObjectUtil.isNotNull(eStudyDataDto.getTitle())){
            query.and(e ->{
                e.like("sd.title",eStudyDataDto.getTitle()).or().like("sd.keywords",eStudyDataDto.getKeywords());
            });
        }
        if(ObjectUtil.isNotNull(eStudyDataDto.getSafeTypeId())){
            query.and(qw->qw.eq("sd.safe_type_id",eStudyDataDto.getSafeTypeId()));
        }
        if(ObjectUtil.isNotNull(eStudyDataDto.getDataType())){
            query.and(qw->qw.eq("sd.data_type",eStudyDataDto.getDataType()));
        }
        if(ObjectUtil.isNotNull(eStudyDataDto.getIsIntroduce())){
            query.and(qw->qw.eq("sd.is_introduce",eStudyDataDto.getIsIntroduce()));
        }
        query.eq("sd.is_deleted",false);
        IPage<EStudyDataDto> eStudyDataIPage=eStudyDataMapper.getAllPage(pageVO.buildPage(),query);
        return eStudyDataIPage;
    }

    @Override
    public void download(List<EStudyDataDto> eStudyDataDtoList, HttpServletResponse response) throws IOException {
        if (CollectionUtil.isEmpty(eStudyDataDtoList)) {
            throw new BadRequestException(ResultEnum.FILE_DOWNLOAD_FAIL_NOT_DATA);
        }
        List<Map<String, Object>> list = new ArrayList<>();
        for(EStudyDataDto eStudyDataDto:eStudyDataDtoList){
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("学习资料id",eStudyDataDto.getId());
            map.put("标题",eStudyDataDto.getTitle());
            map.put("关键词",eStudyDataDto.getKeywords());
            map.put("类型",eStudyDataDto.getName());
            map.put("学习资料封面",eStudyDataDto.getCoverPicLink());
            map.put("点赞数",eStudyDataDto.getTags());
            map.put("是否推荐",eStudyDataDto.getIsIntroduce());
            map.put("学习资料内容",eStudyDataDto.getContent());
            list.add(map);
        }
        FileUtils.downloadExcel(list, response);
    }

    @Override
    public IPage<EStudyData> getFront(PageVO pageVO, EStudyData eStudyData) {
        IPage<Object> page = pageVO.buildPage();
        return eStudyDataMapper.getFront(page,eStudyData);
    }

    @Override
    public IPage<EStudyData> queryAllByEs(StudyDataQueryCriteria criteria, PageVO pageVO) {
        List<EStudyData> eStudyDataList = new ArrayList<>();
        SearchRequest searchRequest = new SearchRequest("study_data");

        // 构建搜索条件
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        if (ObjectUtil.isNotNull(criteria.getKeywords())){
            BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery()
                    .should(QueryBuilders.matchQuery("title", criteria.getKeywords()))
                    .should(QueryBuilders.matchQuery("keywords", criteria.getKeywords()));
            sourceBuilder.query(boolQueryBuilder);

            //构建高亮查询
            HighlightBuilder highlightBuilder = new HighlightBuilder();
            highlightBuilder.requireFieldMatch(true); // 多个高亮显示
            highlightBuilder.field("title");
            highlightBuilder.preTags("<span style='color:red'>").postTags("</span>");
            sourceBuilder.highlighter(highlightBuilder);
        }

        if (ObjectUtil.isNotNull(criteria.getSafeTypeId())) {
            TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("safeTypeId", criteria.getSafeTypeId());
            sourceBuilder.query(termQueryBuilder);
        }

        searchRequest.source(sourceBuilder);
        try {
            SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            for (SearchHit documentFields : searchResponse.getHits().getHits()) {
                Map<String, HighlightField> highlightFields = documentFields.getHighlightFields();
                HighlightField title = highlightFields.get("title");
                Map<String, Object> sourceAsMap = documentFields.getSourceAsMap();// 最开始的结果
                if (ObjectUtil.isNotNull(title)) {
                    Text[] fragments = title.fragments();
                    String n_title = "";
                    for (Text fragment : fragments) {
                        n_title += fragment;
                    }
                    sourceAsMap.put("title", n_title);
                }
                EStudyData eStudyData = BeanUtil.fillBeanWithMap(sourceAsMap, new EStudyData(), false);
                eStudyDataList.add(eStudyData);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        IPage<EStudyData> eStudyDataIPage = new Page<>();
        eStudyDataIPage.setRecords(eStudyDataList);
        return eStudyDataIPage;
    }
}

